import prisma from '../lib/prisma';
import { CreateEvaluationDto, UpdateEvaluationDto, EvaluationStatus, Evaluation } from '../types/evaluation';
import { ApiError } from '../utils/ApiError';
import { StatusCodes } from 'http-status-codes';

export class EvaluationService {
  constructor(private readonly prismaClient = prisma) {}

  async createEvaluation(data: CreateEvaluationDto): Promise<Evaluation> {
    try {
      const evaluation = await this.prismaClient.evaluation.create({
        data: {
          userId: data.userId,
          questionId: data.questionId,
          score: data.score || 0,
          feedback: data.feedback || '',
          status: EvaluationStatus.PENDING,
          submittedAt: new Date()
        }
      });
      return evaluation as Evaluation;
    } catch (error: any) {
      if (error?.code === 'P2002') {
        throw new ApiError(StatusCodes.BAD_REQUEST, 'Invalid evaluation data');
      }
      throw new ApiError(StatusCodes.INTERNAL_SERVER_ERROR, 'Error creating evaluation');
    }
  }

  async updateEvaluation(id: number, data: UpdateEvaluationDto): Promise<Evaluation> {
    try {
      const evaluation = await this.prismaClient.evaluation.update({
        where: { id },
        data: {
          ...data,
          updatedAt: new Date()
        }
      });
      return evaluation as Evaluation;
    } catch (error: any) {
      if (error?.code === 'P2025') {
        throw new ApiError(StatusCodes.NOT_FOUND, 'Evaluation not found');
      }
      throw new ApiError(StatusCodes.INTERNAL_SERVER_ERROR, 'Error updating evaluation');
    }
  }

  async getEvaluation(id: number): Promise<Evaluation> {
    try {
      const evaluation = await this.prismaClient.evaluation.findUnique({
        where: { id }
      });
      if (!evaluation) {
        throw new ApiError(StatusCodes.NOT_FOUND, 'Evaluation not found');
      }
      return evaluation as Evaluation;
    } catch (error) {
      if (error instanceof ApiError) throw error;
      throw new ApiError(StatusCodes.INTERNAL_SERVER_ERROR, 'Error fetching evaluation');
    }
  }

  async getEvaluations(userId?: number): Promise<Evaluation[]> {
    try {
      const where = userId ? { userId } : {};
      const evaluations = await this.prismaClient.evaluation.findMany({ where });
      return evaluations as Evaluation[];
    } catch (error: any) {
      throw new ApiError(StatusCodes.INTERNAL_SERVER_ERROR, 'Error fetching evaluations');
    }
  }

  async deleteEvaluation(id: number): Promise<void> {
    try {
      await this.prismaClient.evaluation.delete({
        where: { id }
      });
    } catch (error: any) {
      if (error?.code === 'P2025') {
        throw new ApiError(StatusCodes.NOT_FOUND, 'Evaluation not found');
      }
      throw new ApiError(StatusCodes.INTERNAL_SERVER_ERROR, 'Error deleting evaluation');
    }
  }
}
